Skip to content

2821. 延迟每个 Promise 对象的解析

2821. 延迟每个 Promise 对象的解析

ts
type Fn = () => Promise<any>

const delayAll = (functions, ms) => {
  return functions.map(
    (fn) => () =>
      new Promise((resolve, reject) =>
        setTimeout(() => {
          fn().then(resolve).catch(reject)
        }, ms)
      )
  )
}

延迟的语义

这里的要求是:每个函数返回的 Promise 至少要等 ms 毫秒后才 resolve/reject,即使函数本身执行得很快。

实现方式就是用 setTimeout 包裹函数调用,延迟 ms 后再执行 fn()。返回值形状保持不变,所以调用方侧的使用方式不需要改。

为什么返回包装函数

delayAll 的返回值是 () => Promise<any>[]——每个元素仍然是一个函数,不是直接执行的 Promise。这和 functions 的签名一致:都是「可执行的任务」,而不是「已启动的任务」。

这样做的意义在于,调用方仍然保留执行时机的控制权,可以按需要并行或串行地启动这些延迟函数。

和 Promise.all 的延迟区别

Promise.all 配合 sleep 也能实现延迟:

ts
const withDelay = fn => () => Promise.all([fn(), sleep(ms)]).then(([r]) => r)

但这种写法下两个 Promise 是同时启动的:如果函数本身很慢,额外的 delay 基本不起作用;如果函数很快,sleep 才会决定最短耗时。而这里的实现是先等 ms 再启动函数,保证的是启动前等待时间,不是总耗时下限